﻿/*
    TeamMatches for Kaixin001.com 

    Copyright (C) 2008, TurboZV, turbozv@gmail.com, http://www.turbozv.com/

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    *KEEP THIS HEADER INFORMATION*
*/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;

using KXCommon;

namespace KaixinHouse
{

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // 存储用户名和密码以及用户编号
    public class UserIdentity
    {
        public string userIdx = null;
        public string userName = null;
        public string userMail = null;
        public string userPass = null;

        public UserIdentity() { }

        public UserIdentity(UserIdentity ac)
        {
            this.userIdx = ac.userIdx;
            this.userName = ac.userName;
            this.userMail = ac.userMail;
            this.userPass = ac.userPass;
        }

        public bool equals(UserIdentity u2)
        {
            if (String.IsNullOrEmpty(this.userIdx))
            {
                if (String.IsNullOrEmpty(u2.userIdx))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            if (String.Compare(this.userIdx, u2.userIdx) == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //用户配置信息类
    public class UserConfig
    {
        public static UserConfig _default = new UserConfig();

        protected string       fileName = null;

        public UserIdentity    master = new UserIdentity();

        public Collection<int> stayList = new Collection<int>(); // 入住用户ID，依次住入用户家中
        public Collection<int> keepList = new Collection<int>(); // 当停在此类用户家中时，该用户不移动

        public int             kickGuest = 0;
        public int             checkExpired = 0;
        public int             moveWait = 3;
        public int             rotateSlaveMove = 0;

        public int             doMove = 0;
        public int             doWork = 1;
        public int             doSlave = 0;
        public int             doGarden = 1;


        public Collection<int> stealList = new Collection<int>(); //偷窃列表，用户在此表中进行偷窃
        public Collection<int> tcareList = new Collection<int>();//种植列表，会去种植列表中共享地上种庄稼
        public Collection<int> sendList = new Collection<int>();//增送列表，会去自动给列表上的人赠送果实

        protected Collection<Garden.Seed> seedList = new Collection<Garden.Seed>(); //使用种子的列表

        public int stealOthers = 0;//是否偷窃其他用户，默认为不偷窃
        public int watchCrops = 0;//是否监视庄稼状态
        public int sellCrops = 0;//是否自动出售庄稼
        public int sendCrops = 0;//是否自动赠送庄稼

        public Collection<UserIdentity> slaveList = new Collection<UserIdentity>();

        public UserConfig() 
        { 
        }
        
        public UserConfig(string filename)
        {
            this.fileName = filename;

            try
            {
                string[] lines = File.ReadAllLines(filename);
                foreach (string line in lines)
                {
                    if (line.StartsWith("Email=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.master.userMail = GetStringValue(line);
                        continue;
                    }

                    if (line.StartsWith("Password=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.master.userPass = GetStringValue(line);
                        continue;
                    }

                    if (line.StartsWith("StayList=", StringComparison.OrdinalIgnoreCase))
                    {
                        GetIntegerListValue(this.stayList, line);
                        continue;
                    }

                    if (line.StartsWith("KeepList=", StringComparison.OrdinalIgnoreCase))
                    {
                        GetIntegerListValue(this.keepList, line);
                        continue;
                    }

                    if (line.StartsWith("StealList=", StringComparison.OrdinalIgnoreCase))
                    {
                        GetIntegerListValue(this.stealList, line);
                        continue;
                    }

                    if (line.StartsWith("CareList=", StringComparison.OrdinalIgnoreCase))
                    {
                        GetIntegerListValue(this.tcareList, line);
                        continue;
                    }

                    if (line.StartsWith("SendList=", StringComparison.OrdinalIgnoreCase))
                    {
                        GetIntegerListValue(this.sendList, line);
                        continue;
                    }

                    if (line.StartsWith("KickGuest=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.kickGuest = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("RotateSlaveMove=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.rotateSlaveMove = GetIntegerValue(line);
                        continue;
                    }

                    //if (line.StartsWith("CallInterval=", StringComparison.OrdinalIgnoreCase))
                    //{
                    //    this.callInterval = GetIntegerValue(line);
                    //    if (this.callInterval > 0)
                    //    {
                    //        _RunTime.setInterval( this.callInterval );
                    //    }
                    //    continue;
                    //}

                    if (line.StartsWith("CheckExpired=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.checkExpired = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("UseSeed=", StringComparison.OrdinalIgnoreCase))
                    {
                        Match match = Regex.Match(GetStringValue(line), @" *([0-9]+) *, *([0-9]+) *, *([\S]*) *");
                        if (match.Success)
                        {
                            Garden.Seed sd = new Garden.Seed();
                            sd.rank = TextParser.GetInteger( match.Result("$1") );
                            sd.seedid = TextParser.GetInteger( match.Result("$2") );
                            sd.name = match.Result("$3");
                            this.seedList.Add(sd);
                        }
                        continue;
                    }

                    if (line.StartsWith("StealOthers=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.stealOthers = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("MoveWait=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.moveWait = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("WatchCrops=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.watchCrops = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("SellCrops=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.sellCrops = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("SendCrops=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.sendCrops = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("DoWork=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.doWork = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("DoMove=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.doMove = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("DoGarden=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.doGarden = GetIntegerValue(line);
                        continue;
                    }

                    if (line.StartsWith("DoSlave=", StringComparison.OrdinalIgnoreCase))
                    {
                        this.doSlave = GetIntegerValue(line);
                        continue;
                    }
                    
                    if (line.StartsWith("Slave=", StringComparison.OrdinalIgnoreCase))
                    {
                        Match match = Regex.Match(GetStringValue(line), @" *([0-9]+) *, *([0-9a-zA-Z_\.@]+) *, *([0-9a-zA-Z]+) *");
                        if (match.Success)
                        {
                            UserIdentity slave = new UserIdentity();
                            slave.userIdx = match.Result("$1");
                            slave.userMail = match.Result("$2");
                            slave.userPass = match.Result("$3");
                            this.slaveList.Add(slave);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                TraceLog.Error(e.Message);
            }

            this.sortSeedListByRank();
        }

        public Garden.Seed getProperSeed(int rank)
        {
            //Set Default Value
            Garden.Seed ret = new Garden.Seed();
            ret.rank = 0;
            ret.seedid = 1;
            ret.name = "胡萝卜";
            if (this.seedList.Count == 0) return ret; 

            int maxlvl = this.seedList[this.seedList.Count-1].rank;
            int minlvl = this.seedList[0].rank;
            int curlvl = rank;

            if (curlvl > maxlvl) curlvl = maxlvl;
            if (curlvl < minlvl) curlvl = minlvl;

            foreach (Garden.Seed sd in this.seedList)
            {
                if (curlvl >= sd.rank)
                {
                    ret = sd;
                }
                else
                {
                    break;
                }
            }
            return ret;        
        }

        //Sort Seed List by User Rank
        protected void sortSeedListByRank()
        {
            int i = 0, j = 0;
            for (i = 0; i < this.seedList.Count; i++)
            {
                for (j = i + 1; j < this.seedList.Count; j++)
                {
                    if (this.seedList[i].rank > this.seedList[j].rank)
                    {
                        Garden.Seed sd = this.seedList[i];
                        this.seedList[i] = this.seedList[j];
                        this.seedList[j] = sd;
                    }
                }
            }
        }

        public static void GetIntegerListValue(Collection<int> list, string line)
        {
            string[] idlist = GetStringValue(line).Split(',');
            foreach (string id in idlist)
            {
                int value = TextParser.GetInteger(id);
                if (-1 != value)
                {
                    list.Add(value);
                }
            }
        }

        public static bool GetBoolValue(string line)
        {
            return ("1" == GetStringValue(line));
        }

        public static int GetIntegerValue(string line)
        {
            string value = GetStringValue(line);

            return TextParser.GetInteger(value);
        }

        public static string GetStringValue(string line)
        {
            return line.Substring(line.IndexOf('=') + 1);
        }
    }



    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //所有组件的基类
    public class Component
    {

        protected Account account = null;
        protected UserIdentity identity = null;
        protected UserConfig config = null;

        public string verifyCode = null;
        protected string baseLink = null;

        protected int cash = 0;
        protected int capital = 0;

        private const int MINCASH = 50000; //维持用户帐户运行，要求该用户最低拥有的金钱数，若低于此资金，robot会自动使用户收益最大化

        public Component()
        {
            this.config = UserConfig._default;
        }

        public Component(Account acc)
        {
            this.account = acc;
            this.identity = acc.identity;
            this.config = acc.config;
        }

        public virtual bool Action() { return true; }

        public string readStartPage()
        {
            string content = null;
            if (!String.IsNullOrEmpty(this.baseLink))
            {
                TraceLog.PrintLn("readStartPage() -> [{0}] ......", this.baseLink);
                content = HttpHelper.inst.Get( this.baseLink );
                this.verifyCode = TextParser.GetVerifyCode(content);
            }
            return content;
        }

        protected bool isAPoorMan()
        {
            return (this.cash < Component.MINCASH);
        }

    }


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public class House :Component
    {
        public const string basename = "!house";

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected Collection<Room> RoomList = new Collection<Room>(); // 用户的房间
        protected Slot staySlot = null;
        protected House visitor = null;
        
        protected DateTime expiredTime = System.DateTime.Now.ToLocalTime();

        protected bool isSlave = false;
        
        //用于Account里面初始化House
        public House(Account acc) : base(acc)
        {
            this.isSlave = false;
            this.baseLink = "http://www.kaixin001.com/app/app.php?aid=1062";
        }
 
        //用于访问其它用户的房间
        public House(House vt, string userIdx) : base()
        {
            this.identity = new UserIdentity();
            this.identity.userIdx = userIdx;
            this.visitor = vt;
            this.isSlave = false;
            this.baseLink = "http://www.kaixin001.com/app/app.php?aid=1062";
        }

        //用于访问Slave的房间
        public House(UserIdentity slvid) : base()
        {
            this.identity = slvid;
            this.isSlave = true; //通过ID初始化的用户均为Slave
            this.baseLink = "http://www.kaixin001.com/app/app.php?aid=1062";
        }

        //执行House的逻辑
        public override bool Action()
        {
            if ((this.config.doMove != 1) && (this.config.doSlave != 1)) return false;

            if (!Account.logon(this.identity)) return false;
            _RunTime.setCurEnv(this.identity.userMail, "house");
            string content = this.readStartPage();

            TextParser tp = new TextParser(content);
            this.cash = TextParser.GetInteger( tp.getStrBtw("<strong style=\"font-family:Arial;font-size:12px;\" title=\"", "元\">") );
            tp.getNextStrBtw();
            this.capital = TextParser.GetInteger(tp.getNextStrBtw());
            TraceLog.PrintLn("用户现金={0}，总资产={1}；", this.cash, this.capital);

            this.findRoomList(content);
            this.findStayStatus(content);
            this.setWatchDog();

            //this.sortSlotList(null);
            //this.sortSlotList(this.RoomList[0]);

            this.procMove();
            this.procSlave();

            return base.Action();
        }

        //移动当前用户到一个房间内
        private int moveThisTo(Room room)
        {
            string fromUserID = this.identity.userIdx;
            string toUserID = room.userIdx;
            string toRoomID = room.roomIdx;

            if ((String.IsNullOrEmpty(fromUserID)) || (String.IsNullOrEmpty(toUserID)) ||
                (String.IsNullOrEmpty(toRoomID)) || (String.IsNullOrEmpty(this.verifyCode)))
            {
                return -1;
            }

            TraceLog.Print("[{0}] move to [{1}] at (ROOM={2}) ......", fromUserID, toUserID, toRoomID);

            string postdata = "verify=" + verifyCode + "&roomid=" + toRoomID + "&tuid=" + toUserID + "&fuid=" + fromUserID + "&status=0";
            string retcode = HttpHelper.inst.Post("http://www.kaixin001.com/house/stayhouse.php", postdata);

            string fuid = "", tuid = "", ret = "";
            string flag = "", cash = "", staycash = "";

            string tmp1 = (new TextParser(retcode)).getStrBtw("reset();parent.", ");");
            if (tmp1 == null) return -1;

            string tmp2 = (new TextParser(tmp1)).getStrBtw("(", "");
            if (tmp2 == null) return -1;

            string func_name = (new TextParser(tmp1)).getStrBtw("", "(");
            if (func_name == null) return -1;

            tmp2 = tmp2.Replace("'", "");
            string[] val = tmp2.Split(',');
            if (val.Length >= 4)
            {
                fuid = val[0];
                tuid = val[1];
                flag = val[2];
                cash = val[3];
            }
            if (val.Length >= 5)
            {
                staycash = val[4];
            }

            switch (TextParser.GetInteger(flag))
            {
                case 0:
                    ret = "Succ";
                    break;
                case 1:
                    ret = "Fail：非好友";
                    break;
                case 2:
                    ret = "Fail：已经成功";
                    break;
                case 3:
                    ret = "Fail：现金不足";
                    break;
                case 4:
                    ret = "Fail：房间人满";
                    break;
                case 5:
                    ret = "Fail：未满1个小时";
                    break;
                case 6:
                    ret = "Fail：非法操作";
                    break;
                case 7:
                    ret = "Fail：连续两次住同一人家里";
                    break;
                case 8:
                    ret = "Fail：网络繁忙";
                    break;
                default:
                    ret = "Fail：未知flag值";
                    break;
            }

            TraceLog.PrintLn(ret);
            TraceLog.PrintLn("Cash= {0}; Stay Cash= {1}", cash, staycash);

            //Write local variables back
            if (TextParser.GetInteger(flag) == 0)
            {
                _RunTime.UMRTouch(this.identity.userIdx);
                this.updateRoomInfo(room);
            }
            return TextParser.GetInteger(flag);
        }

        //如果用户成功移动，更新内存中的数据结构
        private void updateRoomInfo(Room toRoom )
        {
            TraceLog.PrintLn("用户移动成功，更新From/To房间信息");

            //更新From Room
            if ( (this.staySlot != null)&&(this.staySlot.room != null ) )
            {
                foreach (Slot slot in this.staySlot.room.slotList )
                {
                    if (slot.accIdentity.equals(this.identity))
                    {
                        TraceLog.PrintLn("清除房间{0}.{1}的用户停留信息",this.staySlot.room.userIdx, this.staySlot.room.roomIdx);
                        slot.isUsed = false;
                        slot.accIdentity = null;
                        slot.stayMins = -1;
                        slot.dataGetTime = System.DateTime.Now.ToLocalTime();
                        this.staySlot = null;
                        break;
                    }
                }
            }

            //更新To Room
            if (toRoom != null)
            {
                foreach (Slot slot in toRoom.slotList)
                {
                    if (!slot.isUsed)
                    {
                        TraceLog.PrintLn("增加房间{0}.{1}的用户停留信息", toRoom.userIdx, toRoom.roomIdx);
                        slot.isUsed = true;
                        slot.accIdentity = this.identity;
                        slot.dataGetTime = System.DateTime.Now.ToLocalTime();
                        slot.stayMins = 1;
                        this.staySlot = slot;
                        break;
                    }
                }
            }
        }

        //用于在当前用户登陆下，访问其它用户的房间信息
        private House visitHouse(string userIdx)
        {
            House friend = null;
            if (userIdx.CompareTo(this.identity.userIdx) == 0)
            {
                friend = this;
            }
            else
            {
                friend = new House(this, userIdx);
                string content = HttpHelper.inst.Get("http://www.kaixin001.com/app/app.php?aid=1062&url=index.php&_lgmode=pri&fuid=" + userIdx);

                string start = "<a href=\"/home/?uid=" + userIdx + "\" class=\"sl2\">";
                string end = "</a>";
                
                friend.identity.userName = (new TextParser(content)).getStrBtw(start, end);
                friend.findRoomList(content);
            }

            return friend;
        }

        //分析Content内容，得出用户状态
        protected int findStayStatus(string content)
        {

            if (this.isSlave) return 1; 
            if ((this.identity == null) || (String.IsNullOrEmpty(this.identity.userIdx))) return -1;

            this.staySlot = new Slot();

            //Get stay status
            //<span  class="c_sl ">我目前露宿街头</span>
            //<span  class="c_sl ">我目前住在自己家</span>
            //<span  class="c_sl ">他目前住在他自己家</span>
            //<span  class="c_sl ">我目前住在<a href=/~house/index.php?_lgmode=pri&fuid=511207 class='sl noline'>赵大海</a>家</span>
            string status_str;


            //取得用户当前所在位置
            //if ((status_str = Tool.GetMidString(content, "<span  class=\"c_sl \">", "</span>", pos, out newpos)) != null)
            if ((status_str = (new TextParser(content)).getStrBtw("<span  class=\"c_sl \">", "</span>")) != null)
            {
                if (status_str.IndexOf("露宿街头") >= 0)
                {
                    this.staySlot.isUsed = false;
                    this.staySlot.stayName = "[大街上]";
                    this.staySlot.stayMins = -1;
                }
                else
                {
                    this.staySlot.isUsed = true;
                }

                if (status_str.IndexOf("住在自己家") >= 0) this.staySlot.accIdentity = this.identity;
                if (status_str.IndexOf("住在他自己家") >= 0) this.staySlot.accIdentity = this.identity;
                if (status_str.IndexOf("住在她自己家") >= 0) this.staySlot.accIdentity = this.identity;
                if (this.staySlot.accIdentity.equals(this.identity)) this.staySlot.stayName = "[ 自己 ] 家";

                if (status_str.IndexOf("<a href=/~house/index.php?_lgmode=pri&fuid=") >= 0)
                {
                    //this.staySlot.accIdentity.userIdx = Tool.GetMidString(status_str, "<a href=/~house/index.php?_lgmode=pri&fuid=", " class='sl noline'>", pos, out newpos);
                    this.staySlot.accIdentity.userIdx = (new TextParser(status_str)).getStrBtw("<a href=/~house/index.php?_lgmode=pri&fuid=", " class='sl noline'>");

                    //this.staySlot.stayName = Tool.GetMidString(status_str, ">", "<", newpos, out pos);
                    this.staySlot.stayName = (new TextParser(status_str)).getStrBtw(">", "<");
                    this.staySlot.stayName = "[" + this.staySlot.stayName + "] 家";
                }
            }
            TraceLog.PrintLn("[{0}] 住在 {1}，", this.identity.userName, this.staySlot.stayName);


            //取得用户停留时间
            if (this.staySlot.isUsed == false) return 1; //对于露宿街头用户无法计算时间

            House stayFriend = this.visitHouse(this.staySlot.accIdentity.userIdx);
            foreach (Room room in stayFriend.RoomList)
            {
                foreach (Slot slot in room.slotList)
                {
                    if (!slot.isUsed) continue;
                    if (slot.accIdentity.equals(this.identity))
                    {
                        this.staySlot.stayMins = slot.stayMins;
                        this.staySlot.dataGetTime = slot.dataGetTime;
                        this.staySlot.room = room;
                    }
                }
            }
            TraceLog.PrintLn("[{0}] 住了 {1} 分钟。", this.identity.userName, this.staySlot.stayMins);

            return 1;
        }

        //根据用户过期时间调整下次启动时间
        protected void setWatchDog()
        {
            if (this.identity == null) return;
            if (this.staySlot == null) return;
            if (String.IsNullOrEmpty(this.identity.userIdx)) return;

            const int MAX_STAY_TIME = 60 * 24;
            this.expiredTime = System.DateTime.Now.ToLocalTime();

            if ((this.staySlot.isUsed) && (this.config.checkExpired == 1))
            {
                if ((this.staySlot.stayMins >= 0) || (this.staySlot.stayMins <= MAX_STAY_TIME))
                {
                    int kickOutMin = MAX_STAY_TIME - this.staySlot.stayMins;
                    TimeSpan ko_inv = new TimeSpan(0, kickOutMin, 0);
                    this.expiredTime = this.staySlot.dataGetTime + ko_inv;
                    TraceLog.PrintLn("* [{0}] 将在{1}分钟后，于{2}过期！", this.identity.userName, kickOutMin, this.expiredTime);
                    _RunTime.exptRunAt(this.expiredTime);
                }
            }
        }

        //分析Content内容，得出房间列表
        protected int findRoomList(string content)
        {
            if ((this.identity == null) || (String.IsNullOrEmpty(this.identity.userIdx))) return -1;

            this.RoomList = new Collection<Room>();

            //<a href="/!house/index.php?roomid=3805"><img src="http://img.kaixin001.com.cn/i2/house/1h-2.gif"/></a>
            //<a href="/"+House.basename+"/index.php?fuid=511207&roomid=4252">
            //<a href="/"+House.basename+"/index.php?roomid=4252">
            string schstr_local = "<a href=\"/"+House.basename+"/index.php?roomid=";
            string schstr_remote = "<a href=\"/" + House.basename + "/index.php?fuid=" + this.identity.userIdx + "&roomid=";

            //<a href="/"+House.basename+"/index_room.php?roomid=5766
            //<a href="/"+House.basename+"/index_room.php?fuid=12684658&roomid=5766"
            string schstr_only1_local = "<a href=\"/" + House.basename + "/index_room.php?roomid=";
            string schstr_only1_remote = "<a href=\"/" + House.basename + "/index_room.php?fuid=" + this.identity.userIdx + "&roomid=";

            string schstr = null;
            if (content.IndexOf(schstr_local) >= 0)
            {
                schstr = schstr_local;
            }
            else if (content.IndexOf(schstr_remote) >= 0)
            {
                schstr = schstr_remote;
            }
            else if (content.IndexOf(schstr_only1_local) >= 0)
            {
                schstr = schstr_only1_local;
            }
            else if (content.IndexOf(schstr_only1_remote) >= 0)
            {
                schstr = schstr_only1_remote;
            }
            else
            {
                return -1;
            }

            string str_id = null;
            //while ((str_id = Tool.GetMidString(content, schstr, "\"", pos, out newpos)) != null)
            TextParser tp = new TextParser(content, schstr, "\"");
            while ((str_id = tp.getNextStrBtw()) != null)
            {
                //如果是奴隶，不需要获得房间的详细信息，只要有room id就可以了
                if (!this.isSlave)
                {
                    this.RoomList.Add(new Room(this, str_id));
                }
                else
                {
                    this.RoomList.Add(new Room(this.identity.userIdx, str_id));
                }
            }

            return this.RoomList.Count;
        }

        //取得当前用户的最大房间
        private Room getLargestRoom()
        {
            int maxCnt = 0;
            Room retRoom = null;
            foreach (Room room in this.RoomList)
            {
                if (this.isSlave) return room;
                if (room.totalSlots() > maxCnt)
                {
                    maxCnt = room.totalSlots();
                    retRoom = room;
                }
            }
            return retRoom;
        }

        //返回已经由时间长短排序的SlotList
        private Collection<Slot> sortSlotList( Room room )
        {
            Collection<Slot> slotList = new Collection<Slot>();

            //如果Room为空，表示对所有的Slot进行排序
            //取得所有Slot列表
            if (room == null)
            {
                foreach (Room usrRoom in this.RoomList)
                {
                    foreach (Slot slot in usrRoom.slotList)
                    {
                        if (slot.isUsed) slotList.Add(slot);
                    }
                }
            }
            else
            {
                foreach (Slot slot in room.slotList)
                {
                    if (slot.isUsed) slotList.Add(slot);
                }
            }

            //对slot进行排序
            Slot tmp = null;
            int i, j, max = slotList.Count;
            for (i = 0; i < max; i++)
                for (j = i+1; j < max; j++)
                {
                    if (slotList[i].stayMins > slotList[j].stayMins)
                    {
                        tmp = slotList[j];
                        slotList[j] = slotList[i];
                        slotList[i] = tmp;
                    }
                }

        
            //打印输出结果
            foreach (Slot slot in slotList)
            {
                if (slot.accIdentity != null)
                {
                    TraceLog.PrintLn("  - Sort Slot List: {0} @ {1} mins", slot.accIdentity.userIdx, slot.stayMins);
                }
            }
            return slotList;
        }

        //取得停留时间最短的Slave （准备踢出去）
        private UserIdentity getLatestSlave(Room room)
        {
            if (room == null) return null;
            UserIdentity minStayUser = null;
            int minStayTime = 90000;

            foreach (Slot slt in room.slotList)
            {
                if ((slt.isUsed) && (slt.stayMins < minStayTime) && (slt.stayMins > 60))
                {
                    minStayTime = slt.stayMins;
                    minStayUser = slt.accIdentity;
                }
            }

            return minStayUser;
        }

        //根据UserID取得Slave的具体信息，比如登陆信息之类
        private UserIdentity getSlaveIdentity(string userid)
        {
            if (String.IsNullOrEmpty(userid)) return null;

            foreach (UserIdentity slave in this.config.slaveList)
            {
                if (userid.Equals(slave.userIdx))
                {
                    return slave;
                }
            }
            return null;
        }

        //取得停留时间最长的Slave，用于做用户轮换
        private int getOldestSlave(out UserIdentity maxStayUser, out Room userStayRoom)
        {
            maxStayUser = null;
            userStayRoom = null;
            int maxStayTime = 0;

            foreach (Room room in this.RoomList)
            {
                foreach (Slot slt in room.slotList)
                {
                    if ((slt.isUsed) && (slt.stayMins > maxStayTime) && (slt.stayMins > 60))
                    {
                        //如果slot上面的用户不在slavelist里面，说明不是奴隶，继续
                        maxStayUser = this.getSlaveIdentity(slt.accIdentity.userIdx);
                        if (maxStayUser == null) continue;

                        maxStayTime = slt.stayMins;
                        userStayRoom = room;
                    }
                }
            }

            if (maxStayUser == null)
            {
                return 0;
            }
            else
            {
                TraceLog.PrintLn("取得最久之奴隶：{0}， 时间={1}分钟", maxStayUser.userMail, maxStayTime);
                return 1;
            }
        }

        //把停留时间最短的Slave踢出去
        private bool kickLatestUser(Room rm)
        {
            UserIdentity minStayUser = this.getLatestSlave(rm);

            if (minStayUser == null) return false;

            string toUserID = minStayUser.userIdx;
            string toRoomID = rm.roomIdx;

            if ((String.IsNullOrEmpty(toUserID)) || (String.IsNullOrEmpty(toRoomID)) || (String.IsNullOrEmpty(verifyCode))) return false;
            TraceLog.Print(" Drive away: [{0}] in (Room={1})", toUserID, toRoomID);
            string postData = string.Format("verify={0}&tuid={1}&roomid={2}", verifyCode, toUserID, toRoomID);
            string content = HttpHelper.inst.Post("http://www.kaixin001.com/house/driveaway.php", postData);

            bool ret = content.IndexOf(",0);</script>") != -1;
            if (ret)
            {
                TraceLog.PrintLn(" Ok!");
                return true;
            }
            else
            {
                TraceLog.PrintLn(" Failed!");
                return false;
            }
        }

        protected int procMove()
        {
            int ret = -1;
            if (this.config.doMove != 1) return 0;
            if ((this.identity == null) || (this.config == null) || (this.staySlot == null)) return ret;

            //Check keep list
            bool isInKeepList = false;
            int keepUserID = 0;
            foreach (int uid in this.config.keepList)
            {
                if (TextParser.GetInteger(this.staySlot.accIdentity.userIdx) == uid)
                {
                    isInKeepList = true;
                    keepUserID = uid;
                    break;
                }
            }
            if (isInKeepList)
            {
                //主号过了23小时后会自动找房子
                if (this.staySlot.stayMins < 23 * 60)
                {
                    TraceLog.PrintLn("[{0}] 已经停留在 KeepList={1} 的朋友家里！", this.identity.userName, keepUserID);
                    return 0;
                }
                else
                {
                    TraceLog.PrintLn("[{0}] 已经停留了{1}分钟，强制移动到KeepList房子中！", this.identity.userName, this.staySlot.stayMins);
                }
            }

            //Move to stay list
            //TraceLog.PrintLn("[{0}] 不在KeepList房间里面，开始四处游荡 ......", this.accIdentity.userName);
            foreach (int uid in this.config.stayList)
            {
                if (TextParser.GetInteger(this.staySlot.accIdentity.userIdx) == uid) continue; //Skip same room

                TraceLog.PrintLn("看看朋友 StayList={0} 是否有空房间......", uid);
                House friend = this.visitHouse("" + uid);

                //主号只进入最大的房间
                ret = -1;
                Room room = friend.getLargestRoom();
                if (room == null) continue;

                //人满状况下的操作
                if (room.freeSlots() <= 0)
                {
                    //如果是自己的房间且设置踢人，则开始踢人
                    if ((friend.identity.equals(this.identity)) && (this.config.kickGuest == 1))
                    {
                        TraceLog.PrintLn("进入自己房间没有空位，准备踢人......");
                        if (!this.kickLatestUser(room)) continue;
                    }
                }

                //进入房间
                ret = this.moveThisTo(room);

                //保证未满一小时的用户能正常操作
                while ((ret == 5) && (this.config.moveWait > 0))
                {
                    TraceLog.PrintLn("等待 {0} 分钟 ......", this.config.moveWait);
                    Thread.Sleep(this.config.moveWait * 60 * 1000);
                    ret = this.moveThisTo(room);
                }

                //若未满1小时则返回
                if (ret == 5) return ret;

                //若操作成功则返回
                if (ret == 0) return ret;
            }

            return ret;
        }

        private Collection<Room> makeFreeRoomList()
        {
            Room maxRoom = this.getLargestRoom();
            Collection<Room> freeRoomList = new Collection<Room>();

            //制作空闲房间列表
            foreach (Room room in this.RoomList)
            {
                int free_slots = room.freeSlots();

                //如果主号不在本人房间内，保留最大房间的一个位置
                if ((this.staySlot == null) || (this.staySlot.room == null) || (! ( this.staySlot.room.owner.identity.equals(this.identity) )))
                {
                    if (maxRoom.roomIdx.CompareTo(room.roomIdx) == 0)
                    {
                        TraceLog.PrintLn("主号本人不在房间内，保留一个最大房间的slot");
                        free_slots--;
                    }
                }

                //如果有空闲房间的话，加入空闲房间列表
                while (free_slots > 0)
                {
                    TraceLog.PrintLn("添加空闲房间： {0}", room.roomIdx);
                    freeRoomList.Add(room);
                    free_slots--;
                }
            }
            return freeRoomList;
        }

        private Collection<UserIdentity> makeFreeSlaveList()
        {
            //制作空闲奴隶列表
            Collection<UserIdentity> freeSlaveList = new Collection<UserIdentity>();
            foreach (UserIdentity ac in this.config.slaveList)
            {
                bool foundInRoomList = false;
                foreach (Room room in this.RoomList)
                {
                    foreach (Slot slot in room.slotList)
                    {
                        if (!slot.isUsed) continue;
                        if (slot.accIdentity.equals(ac))
                        {
                            foundInRoomList = true;
                            break;
                        }
                    }
                    if (foundInRoomList) break;
                }

                if (!foundInRoomList)
                {
                    TraceLog.PrintLn("发现空闲奴隶： {0} ({1})", ac.userIdx, ac.userMail);
                    freeSlaveList.Add(ac);
                }
            }

            return freeSlaveList;
        }


        private bool moveSlaveTo(UserIdentity slave, Room room, bool moveBack)
        {
            int ret = -1;
            bool result = false;

            if (room != null)
            {
                TraceLog.PrintLn("移动奴隶 {0} 到房间 {1} ......", slave.userMail, room.roomIdx);
            }
            else
            {
                TraceLog.PrintLn("移动奴隶 {0} 到她/他自己的房间 ......", slave.userMail);
            }

            House sl = new House(slave);
            Account.logon(slave);

            TraceLog.PrintLn("取得奴隶 [{0}] 的房间信息 ......", slave.userMail);
            string content = HttpHelper.inst.Get("http://www.kaixin001.com/app/app.php?aid=1062");
            sl.verifyCode = TextParser.GetVerifyCode(content);
            sl.findRoomList(content);

            //执行移动操作
            result = false;
            if (room == null)
            {
                //room = null， 表示奴隶回自己的家
                if ((sl.RoomList.Count > 0))
                {
                    //回自己家的时候没有move back
                    ret = sl.moveThisTo(sl.RoomList[0]);
                    if (ret == 0) result = true;
                }
            }
            else
            {
                if ((ret = sl.moveThisTo(room)) != 0)
                {
                    if ((ret != 5) && (sl.RoomList.Count > 0) && (moveBack))
                    {
                        TraceLog.PrintLn("奴隶返回自己房间 ......");
                        ret = sl.moveThisTo(sl.RoomList[0]);
                    }
                }
                else
                {
                    result = true;
                }
            }

            TraceLog.PrintLn("");
            return result;
        }

        private int moveFreeSlaves(Collection<Room> freeRoomList, Collection<UserIdentity> freeSlaveList)
        {
            //对FreeSlaveList进行排序
            _RunTime.UMRSortList(freeSlaveList);

            //让空闲奴隶列表上的奴隶移动到空闲房间里面去
            int ret = 0, rcnt = 0, scnt = 0;
            while ((rcnt < freeRoomList.Count) && (scnt < freeSlaveList.Count))
            {
                if (_RunTime.needRunAgain()) break;

                UserIdentity slave = freeSlaveList[scnt];
                Room room = freeRoomList[rcnt];

                if (this.moveSlaveTo(slave, room, true))
                {
                    rcnt++;
                }
                scnt++;
            }
            return ret;

        }

        //奴隶定期轮流值班
        private int rotateFreeSlaves(Collection<UserIdentity> freeSlaveList)
        {

            //入住最长的一个奴隶从主人房间里面挪到自己房间中去
            UserIdentity maxStaySlv = null;
            Room userStayRoom = null;
            this.getOldestSlave(out maxStaySlv, out userStayRoom);
            if ((maxStaySlv == null) || (userStayRoom == null)) return 0;

            TraceLog.PrintLn("奴隶 {0} 从主人房间挪到自己房间 ......", maxStaySlv.userMail);
            if (!this.moveSlaveTo(maxStaySlv, null, false))
            {
                return -1;
            }

            //把freeSlaveList中的奴隶顺序挪进去
            _RunTime.UMRSortList(freeSlaveList);
            foreach (UserIdentity slave in freeSlaveList)
            {
                if (_RunTime.needRunAgain()) break;

                if (this.moveSlaveTo(slave, userStayRoom, true))
                {
                    break;
                }
            }
            return 0;
        }

        protected int procSlave()
        {

            int ret = -1;
            if (this.config.doSlave != 1) return 0;
            if ((this.identity == null) || (this.config == null) || (this.staySlot == null)) return ret;

            _RunTime.setCurEnv(this.identity.userMail, "slave");

            //制作空闲奴隶列表
            Collection<UserIdentity> freeSlaveList = this.makeFreeSlaveList(); ;
            //如果没有空闲奴隶则无法进行搬迁
            if (freeSlaveList.Count <= 0)
            {
                TraceLog.PrintLn("未发现空闲奴隶！");
                return ret;
            }


            //制作空闲房间列表
            Collection<Room> freeRoomList = this.makeFreeRoomList();
            //奴隶只在主号房间空闲的状态下才进行搬迁
            if (freeRoomList.Count <= 0)
            {
                TraceLog.PrintLn("未发现空闲房间！");
                if (this.config.rotateSlaveMove == 1)
                {
                    TraceLog.PrintLn("执行奴隶定期轮换机制 ......");
                    ret = this.rotateFreeSlaves(freeSlaveList);
                }
                return ret;
            }

            return this.moveFreeSlaves(freeRoomList, freeSlaveList);
        }


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        //房间槽位类
        public class Slot
        {
            public bool isUsed = false;
            public UserIdentity accIdentity = new UserIdentity();
            public int stayMins = -1;
            public string stayName = null;
            public DateTime dataGetTime = System.DateTime.Now.ToLocalTime();
            public Room room = null;

            public Slot() { }
            public Slot(Room rm)
            {
                this.room = rm;
            }
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        //房间类
        public class Room
        {
            protected string roomLink = null;
            protected bool valid = false;

            public string roomIdx = null;
            public string userIdx = null;
            public House owner = null;
            public Collection<Slot> slotList = new Collection<Slot>();

            public Room(House usr, string rm_id)
            {
                this.owner = usr;
                this.roomIdx = rm_id;
                this.userIdx = usr.identity.userIdx;
                this.roomLink = "http://www.kaixin001.com/" + House.basename + "/index.php?fuid=" + this.userIdx + "&roomid=" + this.roomIdx;

                this.valid = this.readContent();
            }

            public Room(string user_id, string rm_id)
            {
                this.userIdx = user_id;
                this.roomIdx = rm_id;
                this.valid = false;
            }

            public bool isValid()
            {
                return this.valid;
            }

            public int totalSlots()
            {
                return this.slotList.Count;
            }

            public int usedSlots()
            {
                int count = 0;
                foreach (Slot slot in this.slotList)
                {
                    if (slot.isUsed) count++;
                }
                return count;
            }

            public int freeSlots()
            {
                int count = 0;
                foreach (Slot slot in this.slotList)
                {
                    if (!slot.isUsed) count++;
                }
                return count;
            }

            protected bool readContent()
            {
                string content = HttpHelper.inst.Get(this.roomLink);

                //Check guest status
                //<a href='javascript:leavehouse(511207,4252)'
                //<a href='javascript:drive_away(13830164,4252)'
                //<a href='javascript:stayhouse2(511207,0,0)'
                //<a href="javascript:stayhouse(13830192,13830192,5766);"
                this.checkGuest(content, "<a href=\"javascript:stayhouse(", ");", false, 0);
                this.checkGuest(content, "<a href='javascript:leavehouse(", ")'", true, 2);
                this.checkGuest(content, "<a href='javascript:drive_away(", ")'", true, 2);
                this.checkGuest(content, "<a href='javascript:stayhouse2(", ")'", true, 3);

                TraceLog.PrintLn("ROOM-{0}: {1} Used + {2} Free = {3} Total", this.roomIdx, this.usedSlots(), this.freeSlots(), this.totalSlots());

                //TraceLog.Print("ROOM-{0}: ", this.roomIdx);
                foreach (Slot slot in this.slotList)
                {
                    string sign = "[ ]";
                    if (slot.isUsed)
                    {
                        sign = "---";
                        int uid = TextParser.GetInteger(slot.accIdentity.userIdx);
                        int stay_uid = TextParser.GetInteger(this.userIdx);
                    }
                    TraceLog.PrintLn("          {0} {1}({2}M)", sign, slot.accIdentity.userIdx, slot.stayMins);
                }
                //TraceLog.PrintLn("");

                return true;
            }

            private void checkGuest(string content, string startText, string endText, bool isIn, int param_check)
            {
                int guid = 0;
                string idText;
                TextParser tp = new TextParser(content, startText, endText);

                while ((idText = tp.getNextStrBtw()) != null)
                {
                    Slot slot = new Slot(this);

                    slot.isUsed = isIn;

                    List<int> temp = TextParser.GetIntegerList(idText);
                    if ((temp.Count == param_check) && (param_check > 0))
                    {
                        guid = temp[0];
                        if (startText.IndexOf("leavehouse") >= 0)
                        {
                            if (this.owner.visitor != null)
                            {
                                guid = TextParser.GetInteger(this.owner.visitor.identity.userIdx);
                            }
                        }
                        slot.accIdentity.userIdx = "" + guid;
                        slot.stayMins = Room.getGuestStayMins(guid, content);
                        slot.dataGetTime = System.DateTime.Now.ToLocalTime();
                    }

                    this.slotList.Add(slot);
                }
            }

            //Get a guest stay time by guest id
            private static int getGuestStayMins(int guid, string content)
            {
                //<a href="/"+House.basename+"/index.php?fuid=525328" class="sl">赵澜策</a><br>已住18小时整</div>
                string begin = "<a href=\"/"+House.basename+"/index.php?fuid=" + guid + "\" class=\"sl\">";
                string tmp = (new TextParser(content)).getStrBtw(begin, "</div>");
                if (null == tmp) return -1;

                string time = (new TextParser(tmp)).getStrBtw("已住", "");
                if (null == time) return -1;

                return (new TextParser(time)).getTotalMinutes();
            }
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    }


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //用户类
    public class Account 
    {
        public UserConfig   config = null;
        public UserIdentity identity = null;
        public House house = null;
        public Garden garden = null;

        public Account(string fn)
        {
            this.config = new UserConfig(fn);
            this.identity = this.config.master;
            this.house = new House(this);
            this.garden = new Garden(this);
        }

        //专门为Slave.ini提供构造函数
        public Account(UserIdentity uid)
        {
            this.config = UserConfig._default;
            this.identity = uid;
            this.house = new House(this);
            this.garden = new Garden(this);
        }

        // 登录账号 并获取用户 ID
        public static bool logon(UserIdentity acid)
        {
            acid.userName = null;
            acid.userIdx = null;

            if ((String.IsNullOrEmpty(acid.userMail)) || (String.IsNullOrEmpty(acid.userPass)))
            {
                return false;
            }
            TraceLog.Print("Login as [{0}]: ", acid.userMail);

            string content = HttpHelper.inst.Post("http://www.kaixin001.com/login/login.php", 
                "url=%2F&email=" + HttpHelper.EncodePostData(acid.userMail) + "&password=" + HttpHelper.EncodePostData(acid.userPass));

            string strId;

            if ((strId = (new TextParser(content)).getStrBtw("<b class=\"f14\">", "</b>")) != null)
            {
                acid.userName = strId;
            }
            else
            {
                acid.userName = "";
            }


            if (content.IndexOf("<title>我的首页 - 开心网</title>") != -1)
            {
                acid.userIdx = (new TextParser(content)).getStrBtw("我的开心网ID:", "\"");
                TraceLog.PrintLn("Ok!");
                TraceLog.PrintLn("Id={0}, Name={1}", acid.userIdx, acid.userName);
                return true;
            }
            else
            {
                TraceLog.Error("Failed!");
                return false;
            }
        }


        public int doWork()
        {
            if ((this.config.doWork == 1) && (_RunTime.isANewDay()))
            {
                if (!Account.logon(this.identity)) return 0;
                _RunTime.setCurEnv(this.identity.userMail, "work");
                string userID = this.identity.userIdx;

                string content = HttpHelper.inst.Get("http://www.kaixin001.com/"+House.basename+"/jobslist.php");
                string verifyCode = TextParser.GetVerifyCode(content);
                if (content.IndexOf("要注意身体，别累坏了") >= 0)
                {
                    //你正在做餐厅洗碗工，今天不能再干其它工作了！
                    string current_work = (new TextParser(content)).getStrBtw("你正在做", "，今天不能再干其它工作了！");
                    TraceLog.PrintLn("[{0}] is doing {1} ！", userID, current_work);
                    return -1;
                }

                //<div class="l"><input name="petid" type="radio" value="11" /> 做洗浴城领班</div>
                //<div class="l"><input name="petid" type="radio" value="43" /> 做律师</div>
                //<div class="r c9">工资：800元/天</div>
                string petid = null, name = null, tmp = null;
                string maxWkStr = null, maxWkSla = null;
                TextParser tpWk = new TextParser(content, "<input name=\"petid\" type=\"radio\" value=", "</div>");
                TextParser tpSl = new TextParser(content, "<div class=\"r c9\">", "</div>");
                while ((tmp = tpWk.getNextStrBtw()) != null)
                {
                    maxWkStr = tmp;
                    maxWkSla = tpSl.getNextStrBtw();
                }
                //"11" /> 做洗浴城领班
                petid = (new TextParser(maxWkStr)).getStrBtw("\"", "\" /> ");
                name = (new TextParser(maxWkStr)).getStrBtw("/> ", "");
                if ((petid == null) || (name == null)) return -1;

                TraceLog.PrintLn("[{0}] starts to {1}！", userID, name);
                TraceLog.PrintLn(maxWkSla);

                content = HttpHelper.inst.Get("http://www.kaixin001.com/house/dojob.php?verify=" + verifyCode + "&petid=" + petid);
            }
            return 1;
        }

        public bool run()
        {
            //调用房间
            if (_RunTime.needRunAgain()) return false;
            house.Action();

            //调用花园
            if (_RunTime.needRunAgain()) return false;
            garden.Action();

            //用户打工
            if (_RunTime.needRunAgain()) return false;
            this.doWork(); 

            return true;
        }

        public bool run(string exptuser, string exptcomp)
        {
            if (!String.IsNullOrEmpty(exptuser))
            {
                if (!exptuser.Equals(this.identity.userMail))
                {
                    //如果期待运行的不是当前用户，直接返回
                    return false;
                }
            }

            int runComp = 0;
            if (!String.IsNullOrEmpty(exptcomp))
            {
                if (exptcomp.Equals("work")) runComp = 1;
                if (exptcomp.Equals("garden")) runComp = 2;
                if (exptcomp.Equals("house")) runComp = 3;
            }
            if (runComp == 0) return false;

            //if (!Account.logon(this.identity)) return false;

            if (runComp == 1) this.doWork();
            if (runComp == 2) garden.Action();
            if (runComp == 3) house.Action();

            return true;
        }

 
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////


    public class Garden : Component
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public string rank = null;
        public bool hasPlantedMaxSharedFileds = false;

        public Collection<Seed> seedList = null;
        public Collection<Fruit> fruitList = null;

        //用于Account里面初始化Garden
        public Garden(Account acc) : base(acc)
        {
            this.baseLink = "http://www.kaixin001.com/app/app.php?aid=1062&url=garden/index.php";
        }

        public override bool  Action()
        {
            if ((this.config.doGarden == 1))
            {
                if (!Account.logon(this.identity)) return false;
                _RunTime.setCurEnv(this.identity.userMail, "garden");
                this.readStartPage();

                //取得用户当前的种子，以防止浪费
                this.seedList = Seed.makeList(this.verifyCode);

                //处理自家花园
                this.handleGardenOwn();

                //照看朋友花园
                this.handleGardenFriend();

                //盗窃朋友花园
                this.stealGardenFriend();

                TraceLog.PrintLn("");
            }
            return true;
        }

        protected bool stealGardenFriend()
        {
            if ( (this.config.stealList.Count <= 0) && (this.config.stealOthers != 1) )
            { 
                //没有指定偷窃列表
                TraceLog.PrintLn("StealList为空！");
                return false;
            }
            if (this.config.stealOthers == 1)
            { 
                //动态获得偷窃列表
                //http://www.kaixin001.com/house/garden/getfriendmature.php?verify=525328_1062_525328_1240192144_c46cd343a9ad928650d35e033810d8b2&r=0.8011484784074128
                string link = "http://www.kaixin001.com/house/garden/getfriendmature.php?verify=" + this.verifyCode + "&r=" + TextParser.RandomString();
                string content = HttpHelper.inst.Get(link);
                //{"uid":12900966,"realname":"\u5f20\u96c5\u5982","online":0,"icon20":"http:\/\/pic.kaixin001.com\/logo\/90\/9\/20_12900966_1.jpg","blove":0},
                TextParser tp = new TextParser(content, "{\"uid\":", ",");
                string uid = null;
                while ((uid = tp.getNextStrBtw()) != null)
                { 
                    int iuid = TextParser.GetInteger( uid );
                    if ( iuid <= 0 ) continue;
                    if (this.config.stealList.Contains(iuid)) continue;
                    this.config.stealList.Add(iuid);
                }
            }

            TraceLog.PrintLn("开始盗窃朋友的花园 ...... ");
            foreach (int uid in this.config.stealList)
            {
                if (_RunTime.needRunAgain()) break;
                TraceLog.PrintLn("盗窃朋友 = {0} ...... ", uid);

                UserIdentity user = new UserIdentity(); 
                user.userIdx = "" + uid;

                string content = this.readUserConf(uid);
                Collection<Field> fieldList = Field.makeList(content);
                Seed seed = this.config.getProperSeed(TextParser.GetInteger(this.rank));

                int harvested = this.handleFields(fieldList, user, seed);
                TraceLog.PrintLn("");
            }

            return true;
        }

        protected bool handleGardenFriend()
        {
            if (this.config.tcareList.Count <= 0)
            {
                TraceLog.PrintLn("CareList为空！");
                return false;
            }

            //种共享地及照看朋友的花园
            TraceLog.PrintLn("开始照看朋友的花园 ...... ");

            foreach (int uid in this.config.tcareList)
            {
                if (_RunTime.needRunAgain()) break;
                TraceLog.PrintLn("照看朋友 = {0} ...... ", uid);

                UserIdentity user = new UserIdentity(); 
                user.userIdx = ""+uid; 
                string content = this.readUserConf(uid);
                Collection<Field> fieldList = Field.makeList(content);
                Seed seed = this.config.getProperSeed(TextParser.GetInteger(this.rank));

                int harvested = this.handleFields(fieldList, user, seed);
                TraceLog.PrintLn("");
            }
            TraceLog.PrintLn("");
            return true;
        }

        protected bool handleGardenOwn()
        {
            UserIdentity user = new UserIdentity();
            user.userIdx = "0";
            string contentAll = this.readUserConf(TextParser.GetInteger(user.userIdx));

            //取得用户当前资金
            //<cashtip>我的现金余额123590</cashtip>
            string cashstr = TextParser.GetHtmlContent(contentAll, "cashtip");
            this.cash = TextParser.ReadFirstInteger(cashstr);

            //取得用户级别以确定使用的种子
            this.rank = TextParser.GetHtmlContent(contentAll, "rank");
            Seed seed = this.config.getProperSeed(TextParser.GetInteger(this.rank));

            //打印调试信息
            TraceLog.PrintLn("UserLevel={0}, Cash={1}, UseSeed={2}/{3}", this.rank, this.cash, seed.seedid, seed.name);

            //Get FieldList
            Collection<Field> fieldList = Field.makeList(contentAll);

            //处理自己的花园
            TraceLog.PrintLn("处理自己的花园 ......");
            int harvested = this.handleFields(fieldList, user, seed);
            TraceLog.PrintLn("");

            //赠送庄稼, 一天只能赠送一次
            if (_RunTime.isANewDay()) this.sendFruit();

            //贩卖收割的庄稼
            if (harvested > 0) this.sellFruit();

            return true;
        }

        private int sendFruit()
        {

            TraceLog.PrintLn("开始赠送劳动果实 ......");

            if (TextParser.GetInteger(this.rank) < 6)
            {
                TraceLog.PrintLn("用户不满6级，不进行赠送！");
                return 0;
            }

            if (this.isAPoorMan())
            {
                TraceLog.PrintLn("穷人一只，不进行赠送！");
                return 0;
            }

            if (this.config.sendCrops == 0)
            {
                TraceLog.PrintLn("SendCrops==0，不进行赠送！");
                return 0;
            }

            if (this.config.sendList.Count <= 0)
            {
                TraceLog.PrintLn("赠送列表为空，不进行赠送！");
                return 0;
            }

            this.fruitList = Fruit.makeList(this.verifyCode, false);
            int ucnt = 0, fcnt = 0;
            while ((ucnt < this.config.sendList.Count) && (fcnt < fruitList.Count))
            {
                TraceLog.Print("赠送果实 [SD={0}]*{1} 给{2} ......", fruitList[fcnt].seedid, fruitList[fcnt].fruitnum, this.config.sendList[ucnt]);
                string link = "http://www.kaixin001.com/house/garden/presentfruit.php";
                string param = "num=" + fruitList[fcnt].fruitnum + "&pmsg=" + "%3A%2D%29" + "&anon=0&verify=" +
                    this.verifyCode + "&seedid=" + fruitList[fcnt].seedid + "&touid=" + this.config.sendList[ucnt];

                string content = HttpHelper.inst.Post(link, param);

                if (content.IndexOf("succ") >= 0)
                {
                    TraceLog.PrintLn("succ");
                }
                else
                {
                    TraceLog.PrintLn("fail");
                }

                fcnt++;
                ucnt++;
            }

            TraceLog.PrintLn("");
            return 0;
        }

        private int sellFruit()
        {
            TraceLog.PrintLn("开始买出劳动果实 ......");

            if ((this.config.sellCrops == 1)||(this.isAPoorMan()))
            {
                if (this.isAPoorMan()) TraceLog.PrintLn("穷人一只，强制买出所有果实！");

                //GET /house/garden/sellfruit.php?verify=525328%5F1062%5F525328%5F1236134647%5Febff7bfa2d1501e7af474cb17468c99b&all=0&seedid=3&num=1
                TraceLog.Print("Selling all products ...... ");
                string sellContent = HttpHelper.inst.Get("http://www.kaixin001.com/house/garden/sellfruit.php?verify=" + verifyCode + "&all=1&seedid=0&num=1");
                if (sellContent.IndexOf("succ") >= 0)
                {
                    //string totalprice = Tool.GetMidString(sellContent, "<totalprice>", "</totalprice>");
                    string totalprice = (new TextParser(sellContent)).getStrBtw("<totalprice>", "</totalprice>");
                    TraceLog.PrintLn("OK! 获利 = " + totalprice + "元");
                }
            }

            TraceLog.PrintLn("");
            return 0;
        }

        private string readUserConf(int uid)
        {
            //http://www.kaixin001.com/house/garden/getconf.php?verify=12901410_1062_12901410_1237788329_a9c31cc1af75820aba9ee6ac60077ed3&fuid=0&r=0.8050531079061329
            string confLink = "http://www.kaixin001.com/house/garden/getconf.php?verify=" + this.verifyCode + "&fuid=" + uid + "&r=" + TextParser.RandomString();
            return HttpHelper.inst.Get(confLink);
        }

        private bool GardenAction(string actionLink, string fuid, int farmnum, string seedid)
        {
            if (String.IsNullOrEmpty(actionLink)) return false;

            string[] parts = actionLink.Split('/');
            string actionName = "";
            if (parts.Length > 1) actionName = parts[parts.Length - 1];

            TraceLog.Print("{0}.{1}: {2} ......", fuid, farmnum, actionName);

            string param = "r=" + TextParser.RandomString() + "&verify=" + this.verifyCode + "&seedid=" + seedid + "&fuid=" + fuid + "&farmnum=" + farmnum;
            string content = HttpHelper.inst.Post(actionLink, param);

            string succSign = "succ";
            if (content.IndexOf(succSign) >= 0)
            {
                TraceLog.PrintLn(succSign);
                return true;
            }
            else
            {
                TraceLog.PrintLn("fail");
                return false;
            }
        }

        private bool canHarvest(int uid)
        {
            if (uid <= 0) return true;
            if (this.config.stealList.Contains(uid)) return true;
            if (this.config.stealOthers == 1) return true;

            return false;
        }


        //userID == 0, this user.
        protected int handleFields( Collection<Field> fieldlst, UserIdentity user, Seed seed)
        {
            if ((fieldlst == null) || (fieldlst.Count < 1)) return -1;
            if ((seed == null) || (user == null) ) return -1;

            string forUserID = user.userIdx;
            int forUserNbr = TextParser.GetInteger(user.userIdx);

            //抢先进行收割，防止被偷，再做其它操作
            int harvested = 0;
            foreach (Field fld in fieldlst)
            {
                //忽略非法/不可操作土地
                if ((fld.farmnum < 0) || (fld.status == 0)) continue;

                //设置下次运行时间，只有庄稼处于生长阶段，并且指定了照看庄稼，并且庄稼的主人是自己
                if ((fld.cropsstatus == 1) && (this.config.watchCrops == 1) && (forUserNbr == 0))
                {
                    _RunTime.exptRunAt(fld.harvestTime);
                }

                //如果可以收获，收割, BTW: 对于好友，这就是盗窃
                if ((fld.cropsstatus == 2) && (this.canHarvest(forUserNbr)))
                {
                    if (GardenAction("http://www.kaixin001.com/house/garden/havest.php", forUserID, fld.farmnum, "0"))
                    {
                        fld.cropsstatus = 3;
                        harvested++;
                    }
                }
            }

            //做除收割之外的其它操作
            foreach (Garden.Field fld in fieldlst)
            {
                //忽略非法/不可操作/共享地块
                if ((fld.farmnum < 0) || (fld.status == 0)) continue;

                //判断是否需要中止此用户的操作
                if ((this.hasPlantedMaxSharedFileds) && (forUserNbr != 0)) break;

                //如果状态不正常，除害，目前只做记录
                if ((fld.status != 1) || (fld.cropsstatus > 3))
                {
                    TraceLog.PrintLn("{0}.{1}: status={2}, corpsstatus={3}", forUserID, fld.farmnum, fld.status, fld.cropsstatus);
                    TraceLog.PrintLn(fld.farm);
                    TraceLog.PrintLn(fld.crops);
                    //continue;
                }

                //浇水
                if ((fld.water < 5) && (GardenAction("http://www.kaixin001.com/house/garden/water.php", forUserID, fld.farmnum, "0")))
                {
                    fld.water = 5;
                }

                //除虫
                if ((fld.vermin == 1) && (GardenAction("http://www.kaixin001.com/house/garden/antivermin.php", forUserID, fld.farmnum, "0")))
                {
                    fld.vermin = 0;
                }

                //除草
                if ((fld.grass == 1) && (GardenAction("http://www.kaixin001.com/house/garden/antigrass.php", forUserID, fld.farmnum, "0")))
                {
                    fld.grass = 0;
                }

                //判断土地能否进行操作
                bool operational = false;
                //如果是本人的土地，则非共享的是可以操作的
                if ((forUserNbr == 0) && (fld.shared != 1)) operational = true;

                //如果是朋友的土地，则共享的是可以操作的
                //不种共享地，只照顾共享地 2009-3-30
                //if ((forUserNbr != 0) && (fld.shared == 1)) operational = true;

                //如果土地可以操作，则进行锄地/买种子/播种等操作
                if (operational)
                {
                    //如果正常生长，不做任何事情
                    if (fld.cropsstatus == 1) continue;

                    //如果已经收获过，锄地
                    if ((fld.cropsstatus == 3) || (fld.cropsstatus == -1))
                    {
                        if (GardenAction("http://www.kaixin001.com/house/garden/plough.php", "0", fld.farmnum, "0"))
                        {
                            fld.cropsstatus = -1;
                        }
                    }

                    //没有庄稼，买种子，并播种
                    if (fld.cropsstatus == -1) this.seeding(forUserNbr, fld, seed);
                }
            }
            return harvested;
        }

        private bool hasSeed(Seed seed)
        {
            if (this.seedList == null) return false;
            foreach (Seed sd in this.seedList)
            {
                if ((sd.seednum > 0) && (sd.seedid == seed.seedid))
                {
                    //sd.seednum--;
                    return true;
                }
            }
            return false;
        }

        private void addSeed(Seed seed, int count)
        {
            if (this.seedList == null) return;
            foreach (Seed sd in this.seedList)
            {
                if (sd.seedid == seed.seedid)
                {
                    sd.seednum = sd.seednum + count;
                    break;
                }
            }
        }

        private int seeding( int forUserNbr, Field fld, Seed seed)
        {
            string content = null;

            if ((this.hasPlantedMaxSharedFileds) && (forUserNbr != 0))
            {
                TraceLog.PrintLn("用户已经种植了最大数目的共享地！");
                return -1;
            }

            //买种子
            //如果用户当前列表里面没有这个种子，则重新购买该种子
            if (!this.hasSeed(seed))
            {
                TraceLog.Print("{0}.{1}: buyseed[{2}:{3}] ......", forUserNbr, fld.farmnum, seed.seedid, seed.name);
                content = HttpHelper.inst.Get("http://www.kaixin001.com/house/garden/buyseed.php?verify=" + this.verifyCode +
                                                     "&seedid=" + seed.seedid + "&num=1");
                if (content.IndexOf("succ") >= 0)
                {
                    TraceLog.PrintLn("succ");
                    this.addSeed(seed, 1);
                }
                else
                {
                    TraceLog.PrintLn("fail");
                    return 0;
                }
            }

            //播种
            if (forUserNbr == 0)
            {
                //自己的土地，用POST方式进行播种
                if (GardenAction("http://www.kaixin001.com/house/garden/farmseed.php", "0", fld.farmnum, "" + seed.seedid))
                {
                    fld.cropsstatus = 1;
                    this.addSeed(seed, -1);
                }
            }
            else
            {
                TraceLog.Print("{0}.{1}: farmseed(Get)[{2}:{3}] ......", forUserNbr, fld.farmnum, seed.seedid, seed.name);
                //对于朋友的土地，种植的方式与自己的土地稍有不同
                //http://www.kaixin001.com/house/garden/farmseed.php?fuid=16006922&r=0%2E06305704452097416&verify=525328%5F1062%5F525328%5F1238138816%5F9f9ba13d79b9126ce12d95281e80fbf5&seedid=17&farmnum=6
                content = HttpHelper.inst.Get("http://www.kaixin001.com/house/garden/farmseed.php?fuid=" + forUserNbr + 
                                              "&r=" + TextParser.RandomString() + 
                                              "&verify=" + this.verifyCode + 
                                              "&seedid=" + seed.seedid + 
                                              "&farmnum=" + fld.farmnum);
                if (content.IndexOf("succ") >= 0)
                {
                    TraceLog.PrintLn("succ");
                    this.addSeed(seed, -1);
                }
                else
                {
                    TraceLog.PrintLn("fail");
                    //<reason>你目前的级别，最多同时可种5块好友的地</reason>
                    string reason = TextParser.GetHtmlContent(content, "reason");
                    if ( !String.IsNullOrEmpty( reason ) )
                    {
                        TraceLog.PrintLn(reason);
                        if (reason.IndexOf("最多同时可种") >= 0) this.hasPlantedMaxSharedFileds = true;
                    }
                }
            }

            return 0;
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public class Fruit
        {
            public static Collection<Fruit> makeList(string verifyCode, bool detailedInfo)
            {
                Collection<Fruit> fruitList = new Collection<Fruit>();

                //取得仓库内所有的果实列表
                string link = "http://www.kaixin001.com/house/garden/mygranary.php?verify=" + verifyCode + "&r=" + TextParser.RandomString();
                string content = HttpHelper.inst.Get(link);
                if (content.IndexOf("succ") < 0) return fruitList;

                TextParser tp = new TextParser(content, "<item>", "</item>");
                string subCon = null;
                while ((subCon = tp.getNextStrBtw()) != null)
                {
                    Fruit ft = new Fruit();
                    ft.seedid = TextParser.GetInteger( TextParser.GetHtmlContent(subCon, "seedid") );
                    ft.fruitnum = TextParser.GetInteger( TextParser.GetHtmlContent(subCon, "num") );
                    fruitList.Add(ft);
                }

                //根据Fruit的数量多少对其进行排序
                int i = 0, j = 0;
                for (i = 0; i < fruitList.Count; i++)
                {
                    for (j = i + 1; j < fruitList.Count; j++)
                    {
                        if (fruitList[i].fruitnum < fruitList[j].fruitnum)
                        { 
                            Fruit ft = fruitList[i];
                            fruitList[i] = fruitList[j];
                            fruitList[j] = ft;
                        }
                    }
                }

                //打印调试信息
                TraceLog.Print("仓库里有{0}种果实：", fruitList.Count);
                foreach (Fruit ft in fruitList)
                {
                    TraceLog.Print("[SD={0}]*{1}, ", ft.seedid, ft.fruitnum);
                }
                TraceLog.PrintLn("");

                if (detailedInfo)
                {
                    //取得单个果实的具体信息
                    foreach (Fruit ft in fruitList)
                    {
                        link = "http://www.kaixin001.com/house/garden/myfruitinfo.php?seedid=" + ft.seedid + "&verify=" + verifyCode + "&r=" + TextParser.RandomString();
                        content = HttpHelper.inst.Get(link);
                        if (content.IndexOf("succ") < 0) continue;

                        ft.fruitprice = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruitprice"));
                        ft.selfnum = TextParser.GetInteger(TextParser.GetHtmlContent(content, "selfnum"));
                        ft.bpresent = TextParser.GetInteger(TextParser.GetHtmlContent(content, "bpresent"));
                        ft.fruit_maxprice = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruit_maxprice"));

                        TraceLog.PrintLn("果实SD-{0},持有{1}份，单价{2}元，供赠送={3}", ft.seedid, ft.fruitnum, ft.fruitprice, ft.bpresent);
                    }
                }
                return fruitList;
            }

            public int seedid;
            public int fruitnum;

            public int fruitprice;
            public int selfnum;
            public int bpresent;
            public int fruit_maxprice;

            public Fruit() { }

        }


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public class Field
        {
            public int water = -1;
            public int farmnum = -1;
            public int vermin = 0;  // vermin == 1 有害虫  vermin == 0 无害虫
            public int cropsid = -1;
            public int fuid = -1;
            public int status = 0; //status == 0 不可操作   status == 1 正常   sattus == 2 干旱
            public int shared = -1;
            public int cropsstatus = -1; //cropsstatus == -1 没有庄稼  cropsstatus == 1  成长中   cropsstatus == 2  可以收获   cropsstatus == 3  收获过
            public int grow = -1;
            public int totalgrow = -1;
            public int fruitnum = -1;
            public int seedid = -1;
            public string crops = null;
            public string farm = null;
            public int grass = 0; // grass == 0 无杂草   grass == 1 需要除草
            public bool stealed = false;
            public DateTime harvestTime = System.DateTime.Now.ToLocalTime().AddDays(1);
            public static DateTime captureTime;

            public Field(string content)
            {
                this.water = TextParser.GetInteger(TextParser.GetHtmlContent(content, "water"));
                this.farmnum = TextParser.GetInteger(TextParser.GetHtmlContent(content, "farmnum"));
                this.vermin = TextParser.GetInteger(TextParser.GetHtmlContent(content, "vermin"));
                this.cropsid = TextParser.GetInteger(TextParser.GetHtmlContent(content, "cropsid"));
                this.fuid = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fuid"));
                this.status = TextParser.GetInteger(TextParser.GetHtmlContent(content, "status"));
                this.shared = TextParser.GetInteger(TextParser.GetHtmlContent(content, "shared"));
                this.cropsstatus = TextParser.GetInteger(TextParser.GetHtmlContent(content, "cropsstatus"));
                this.grow = TextParser.GetInteger(TextParser.GetHtmlContent(content, "grow"));
                this.totalgrow = TextParser.GetInteger(TextParser.GetHtmlContent(content, "totalgrow"));
                this.fruitnum = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruitnum"));
                this.seedid = TextParser.GetInteger(TextParser.GetHtmlContent(content, "seedid"));
                this.grass = TextParser.GetInteger(TextParser.GetHtmlContent(content, "grass"));
                this.crops = TextParser.GetHtmlContent(content, "crops");
                this.farm = TextParser.GetHtmlContent(content, "farm");
                if ((this.crops != null) && (this.crops.IndexOf("已偷过") >= 0)) this.stealed = true;
                if ((this.crops != null) && (this.crops.IndexOf("距离收获：") >= 0))
                {
                    //string havestTime = Tool.GetMidString(this.crops, "距离收获：", "&lt;");
                    string havestTime = (new TextParser(this.crops)).getStrBtw("距离收获：", "&lt;");
                    int intMin = (new TextParser(havestTime)).getTotalMinutes();
                    this.harvestTime = Field.captureTime.AddMinutes(intMin);
                }
                if ((this.crops != null) && (this.crops.IndexOf("即将成熟") >= 0))
                {
                    //即将成熟的果子，过5分钟再来看
                    this.harvestTime = Field.captureTime.AddMinutes(5);
                }

                this.crops = this.removeHTML(this.crops);
                this.farm = this.removeHTML(this.farm);
            }

            private string removeHTML(string str)
            {
                string ret = null;
                if (str != null)
                {
                    ret = str.Replace("&lt;", "<");
                    ret = ret.Replace("&gt;", ">");
                    ret = ret.Replace("<br>", "; ");
                    ret = TextParser.NoHtml(ret);
                }
                return ret;
            }

            public static Collection<Field> makeList(string content)
            {
                Field.captureTime = System.DateTime.Now.ToLocalTime();
                Collection<Field> flst = new Collection<Field>();
                TextParser tp = new TextParser(content, "<item>", "</item>");
                string subContent = null;
                while ((subContent = tp.getNextStrBtw()) != null)
                {
                    Field fld = new Field(subContent);
                    flst.Add(fld);
                    TraceLog.PrintLn("  - [{0}]: SD={1}, WT={2}, VR={3}, GS={4}, SHR={5}, ST={6}, CST={7}", 
                        fld.farmnum, fld.seedid, fld.water, fld.vermin, fld.grass, fld.shared,fld.status, fld.cropsstatus);
                    if (fld.crops != null)
                    {
                        TraceLog.PrintLn("        {0}; {1}", fld.crops, fld.farm);
                    }
                }
                return flst;
            }

        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public class Seed
        {
            public int seedid = -1;
            public string name = null;
            public int rank = -1;
            public int mhours = -1;
            public int price = -1;
            public int minprice = -1;
            public int maxprice = -1;
            public int minnum = -1;
            public int maxnum = -1;
            public int antisteal = -1;
            public int seednum = 0;

            public Seed()
            { 
            
            }

            public Seed(int sID, string content)
            {
                this.seedid = sID;

                this.name = TextParser.GetHtmlContent(content, "name");
                this.rank = TextParser.GetInteger(TextParser.GetHtmlContent(content, "rank"));
                this.mhours = TextParser.GetInteger(TextParser.GetHtmlContent(content, "mhours"));
                this.price = TextParser.GetInteger(TextParser.GetHtmlContent(content, "price"));
                this.minprice = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruit_minprice"));
                this.maxprice = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruit_maxprice"));
                this.minnum = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruit_minnum"));
                this.maxnum = TextParser.GetInteger(TextParser.GetHtmlContent(content, "fruit_maxnum"));
                this.antisteal = TextParser.GetInteger(TextParser.GetHtmlContent(content, "antistealdays"));
            }

            public static Collection<Seed> makeList(string verifyCode)
            { 
                Collection<Seed> seedList = new Collection<Seed>();

                //取得仓库内所有的果实列表
                string link = "http://www.kaixin001.com/house/garden/myseedlist.php?verify=" + verifyCode + "&page=1&r=" + TextParser.RandomString();
                string content = HttpHelper.inst.Get(link);
                if (content.IndexOf("succ") < 0) return seedList;

                TextParser tp = new TextParser(content, "<item>", "</item>");
                string subCon = null;
                while ((subCon = tp.getNextStrBtw()) != null)
                {
                    Seed sd = new Seed();
                    sd.seednum = TextParser.GetInteger( TextParser.GetHtmlContent(subCon, "num") );
                    sd.seedid = TextParser.GetInteger(TextParser.GetHtmlContent(subCon, "seedid"));
                    sd.name = TextParser.GetHtmlContent(subCon, "name");
                    seedList.Add(sd);
                }

                TraceLog.Print("种子列表里有：");
                foreach (Seed sd in seedList)
                {
                    TraceLog.Print("[SD={0}]*{1}, ", sd.seedid, sd.seednum);
                }
                TraceLog.PrintLn("");

                return seedList;
            }

            public static void printAllSeedInfo(string verifyCode)
            {
                int seedid = 1;
                while (true)
                {
                    string link = "http://www.kaixin001.com/house/garden/seedinfo.php?seedid=" + seedid + "&verify=" + verifyCode + "&r=" + TextParser.RandomString();
                    string content = HttpHelper.inst.Get(link);

                    if (null == content) break;
                    if (content.IndexOf("succ") < 0) break;

                    Seed sd = new Seed(seedid, content);
                    TraceLog.PrintLn("{0}   {1} {2} {3} {4} {5} {6} {7} {8} {9} ", 
                        sd.seedid, sd.name, sd.rank, sd.minnum, sd.maxnum, sd.mhours, sd.antisteal, 
                        sd.price, sd.minprice, sd.maxprice);
                    seedid++;
                }
            }
        }

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////




    public class _RunTime
    {
        private static int loopCounter = 0;
        //private static int callInterval = GlobalConfigHelper.config.RepeatTime;

        private static DateTime startTime = System.DateTime.Now.ToLocalTime();
        private static DateTime lastStartTime = System.DateTime.Now.ToLocalTime().AddDays(-1);
        private static DateTime endTime = System.DateTime.Now.ToLocalTime();
        private static DateTime schdNextRun = System.DateTime.Now.ToLocalTime();
        private static DateTime exptNextRun = System.DateTime.Now.ToLocalTime();

        private static string exptUserMail = null;
        private static string exptCompName = null;
        private static string currUserMail = null;
        private static string currCompName = null;

        private static bool isUrgentCall = false;

        //用户移动记录
        private static Collection<UserMoveRec> UserMoveRecList = new Collection<UserMoveRec>();
        protected class UserMoveRec
        {
            public string userIdx;
            public DateTime moveTime = System.DateTime.Now.ToLocalTime();

            public UserMoveRec(string uid)
            {
                this.userIdx = uid;
            }
            public void refresh()
            {
                this.moveTime  = System.DateTime.Now.ToLocalTime();
            }
            public static bool isEarlierThan(UserMoveRec u1, UserMoveRec u2)
            {
                //视空值为最悠久的记录

                if ((u1 == null) && (u2 == null)) return false;
                if ((u1 != null) && (u2 == null)) return false;
                if ((u1 == null) && (u2 != null)) return true;

                return (u1.moveTime < u2.moveTime);
            }
        }

        //根据给定userid在查找用户的移动记录
        protected static UserMoveRec getUMRbyID(string uid)
        {
            foreach (UserMoveRec umr in _RunTime.UserMoveRecList)
            {
                if (umr.userIdx.Equals(uid)) return umr;
            }
            return null;
        }

        //更新用户移动记录
        public static void UMRTouch(string uid)
        {
            if (string.IsNullOrEmpty(uid)) return;

            UserMoveRec curUMR = getUMRbyID(uid);
            if (curUMR == null)
            {
                curUMR = new UserMoveRec(uid);
                _RunTime.UserMoveRecList.Add(curUMR);
            }

            TraceLog.PrintLn("  * UMR: Touch UserIDX={0}", uid);
            curUMR.refresh();
        }

        //根据_RunTime.UserMoveRecList对Slave列表，按照时间先后进行排序
        public static Collection<UserIdentity> UMRSortList(Collection<UserIdentity> uil)
        {
            UserIdentity tmp = null;

            //对列表进行冒泡排序，时间最久的人排在最前面
            
            int i = 0, j = 0, MxLen = uil.Count;
            for (i = 0; i < MxLen; i++)
            {
                for (j = i+1; j < MxLen; j++)
                {
                    if (UserMoveRec.isEarlierThan(getUMRbyID( uil[j].userIdx ), getUMRbyID( uil[i].userIdx )))
                    {
                        tmp = uil[j];
                        uil[j] = uil[i];
                        uil[i] = tmp;
                    }
                }
            }

            //打印调试信息
            foreach (UserIdentity uid in uil)
            {
                UserMoveRec umri = getUMRbyID(uid.userIdx);
                if (umri != null)
                {
                    TraceLog.PrintLn("  * UMR SortResult: {0} @ {1}", umri.userIdx, umri.moveTime);
                }
                else
                {
                    TraceLog.PrintLn("  * UMR SortResult: {0} @ Not recorded", uid.userIdx);
                }
            }

            return uil;
        }

        public static void setCurEnv(string usermail, string compname)
        {
            //compname: move, slave, garden, work
            _RunTime.currUserMail = usermail;
            _RunTime.currCompName = compname;

            TraceLog.PrintLn("");
            TraceLog.PrintLn(">>>>>>  User={0}, Comp={1} <<<<<<", _RunTime.currUserMail, _RunTime.currCompName);
        }

        public static void exptRunAt( DateTime exp )
        {
            //多期待几分钟，因为可能有计时不准确的情况，同时可以避免冲突
            exp = exp.AddMinutes(2);

            //如果新设置的期待时间比原来的期待时间早，使用新设置的期待时间
            if ((exp != null) && (exp < _RunTime.exptNextRun))
            {
                TraceLog.PrintLn("  * EXPECTED Next Run Time: {0} -> {1} !", _RunTime.exptNextRun, exp);
                _RunTime.exptNextRun = exp;
                _RunTime.exptUserMail = _RunTime.currUserMail;
                _RunTime.exptCompName = _RunTime.currCompName;
            }
        }

        //public static void setInterval(int itl)
        //{
        //    _RunTime.callInterval = itl;
        //}

        //检查程序是否需要再次被调用
        public static bool needRunAgain()
        {
            if (GlobalConfigHelper.config.RepeatTime == 0) return false;

            if (_RunTime.schdNextRun <= System.DateTime.Now.ToLocalTime())
            {
                TraceLog.PrintLn("  * SCHEDULE Break! ");
                return true;
            }
            if (_RunTime.exptNextRun <= System.DateTime.Now.ToLocalTime())
            {
                TraceLog.PrintLn("  * EXPECT Break! ");
                return true;
            }
            return false;
        }

        public static bool isANewDay()
        {
            if (startTime.Day != lastStartTime.Day)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private static void loopStart()
        {
            if (!_RunTime.isUrgentCall)
            {
                TraceLog.PrintLn("  * LOOP - [{0}] starts ......", ++_RunTime.loopCounter);

                //每次循环均重设 _RunTime.schdNextRun 为下次运行值
                _RunTime.schdNextRun = System.DateTime.Now.ToLocalTime().AddMinutes(GlobalConfigHelper.config.RepeatTime);
                _RunTime.exptNextRun = _RunTime.schdNextRun;
                TraceLog.PrintLn("  * SCHEDULED next run set to: {0}!", _RunTime.schdNextRun);

                //记录开始时间
                _RunTime.startTime = System.DateTime.Now.ToLocalTime();
            }
            else
            {
                TraceLog.PrintLn("  * URGENT call starts ......");
            }
        }

        private static void loopEnd()
        {
            if (!_RunTime.isUrgentCall)
            {
                //记录结束时间
                _RunTime.endTime = System.DateTime.Now.ToLocalTime();

                //记录下程序开始运行时间，下次运行时，看看是不是新的一天
                _RunTime.lastStartTime = _RunTime.startTime;
            }
            else
            { 
                //如果是紧急调用，清除紧急调用下次运行时间
                _RunTime.isUrgentCall = false;
                _RunTime.exptNextRun = System.DateTime.Now.ToLocalTime().AddDays(1);
            }
        }

        private static int getSleepMins()
        {
            TimeSpan inv;

            if (_RunTime.exptNextRun < _RunTime.schdNextRun)
            {
                _RunTime.isUrgentCall = true;
                inv = _RunTime.exptNextRun - System.DateTime.Now.ToLocalTime();
            }
            else
            {
                _RunTime.isUrgentCall = false;
                inv = _RunTime.schdNextRun - System.DateTime.Now.ToLocalTime();
            }

            return (int)inv.TotalMinutes;
        }

        private static void restSomeMins( int restTime )
        {
            while (restTime > 0)
            {
                TraceLog.PrintLn("  * Wait {0} mins to restart...", restTime--);
                Thread.Sleep(60 * 1000);
                if (_RunTime.needRunAgain()) break;
            }
        }

        protected static void runonce()
        {
            
            string appName = Process.GetCurrentProcess().MainModule.FileName;
            string[] filelist = Directory.GetFiles(Path.GetDirectoryName(appName), "*.ini");
            Array.Sort(filelist);

            _RunTime.loopStart();
            foreach (string filename in filelist)
            {
                try
                {
                    TraceLog.PrintLn("读取账号文件: " + filename);
                    if (filename.IndexOf("Slave") >= 0)
                    {
                        //处理Slave.ini
                        UserConfig._default = new UserConfig(filename);
                        Collection<UserIdentity> slaveList = UserConfig._default.slaveList;
                        UserConfig._default.slaveList = new Collection<UserIdentity>();

                        foreach (UserIdentity uid in slaveList)
                        {
                            UserConfig._default.master = uid;
                            UserConfig._default.sendList = new Collection<int>();
                            UserConfig._default.sendList.Add( TextParser.GetInteger(uid.userIdx) );

                            uid.userIdx = null;

                            Account acc = new Account(uid);
                            acc.run();
                        }
                    }
                    else
                    {
                        Account acc = new Account(filename);
                        if (_RunTime.isUrgentCall)
                        {
                            acc.run(_RunTime.exptUserMail, _RunTime.exptCompName);
                        }
                        else
                        {
                            acc.run();
                        }
                    }
                }
                catch (Exception e)
                {
                    TraceLog.Error(e.Message);
                }
            }
            _RunTime.loopEnd();

            _RunTime.restSomeMins( _RunTime.getSleepMins() );
        }

        public static void execute(string[] args)
        {

            if (args.Length >= 1)
            {
                //string[] test = { "-u", "seaza@sina.com", "-p", "iforgot", "-moveto", "12684807:5766" };
                //UserOperations.CallByParams(args);
                if (args[0].Equals("seedinfo"))
                {
                    UserIdentity tuid = new UserIdentity();
                    tuid.userMail = "cao_cao_bj@163.com";
                    tuid.userPass = "iforgot";

                    Account tacc = new Account(tuid);
                    Account.logon(tuid);
                    tacc.garden.readStartPage();
                    Garden.Seed.printAllSeedInfo(tacc.garden.verifyCode);
                }
            }
            else
            {
                while (true)
                {
                    _RunTime.runonce();

                    //如果RepeatTime == 0， 只执行一次
                    if (GlobalConfigHelper.config.RepeatTime == 0) break;
                }
            }
        }
    }


}
